package com.sh.caryr.erp.controller.product;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.sh.caryr.erp.entity.PageResultMessage;
import com.sh.caryr.erp.entity.ResultMessage;
import com.sh.caryr.erp.entity.basis.CompCfg;
import com.sh.caryr.erp.entity.definition.CommonFieldDef;
import com.sh.caryr.erp.exception.ResultCode;
import com.sh.caryr.erp.service.ICompCfgService;
import com.sh.caryr.erp.service.external.entity.ExtProduct;
import com.sh.caryr.erp.entity.product.ProductMapping;
import com.sh.caryr.erp.entity.user.User;
import com.sh.caryr.erp.exception.RestServiceException;
import com.sh.caryr.erp.service.external.helper.ExtServiceHelper;
import com.sh.caryr.erp.mapper.ProductMappingMapper;
import com.sh.caryr.erp.service.IProductMappingService;
import com.sh.caryr.erp.service.external.ExtServiceFactory;
import com.sh.caryr.erp.service.external.ExtProductService;
import com.sh.caryr.erp.util.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/productMapping")
@SessionAttributes("user")
public class ProductMappingController {

    @Autowired
    private IProductMappingService productMappingService;

    @Autowired
    private ExtServiceFactory extServiceFactory;

    @Autowired
    private ICompCfgService compCfgService;

    @ApiOperation(value = "Get Count", notes = "Get Count")
    @RequestMapping(value = "/count", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    public ResultMessage<JSONObject> countProducts(@ModelAttribute("user") User operator) {
        Wrapper<ProductMapping> wrapper = MyBatisUtil.getIsActiveWrapper();
        MyBatisUtil.addAuthFilter(MyBatisUtil.getIsActiveWrapper(), operator, ERPConstants.AUTH_TARGET_PROMAPPING, false, true);
        JSONObject counts = new JSONObject();
        counts.put(CommonFieldDef.FRONT_COUNT_TOTAL, productMappingService.selectCount(wrapper));
        counts.put(CommonFieldDef.FRONT_COUNT_FINISH, productMappingService.selectCount(wrapper.isNotNull(CommonFieldDef.PRO_MAPPING_SPEC_ID)));
        return new ResultMessage<>(counts);
    }

    @ApiOperation(value = "获取产品对接列表,支持分页，支持多个查询条件（多个条件用','隔开），支持单个排序", notes = "获取产品列表信息")
    @RequestMapping(method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    public PageResultMessage<List<ProductMapping>> findProductMappings(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "20") Integer size,
            @RequestParam(name = "search[value]", required = false) String filters,
            @RequestParam(defaultValue = "id") String orderBy,
            @RequestParam(defaultValue = "false") Boolean isAsc,
            @ModelAttribute("user") User operator) {
        orderBy = StringUtils.isNotEmpty(orderBy) ? orderBy : ProductMappingMapper.DEFAULT_ORDER_BY;
        size = MyBatisUtil.SELECT_ALL == size || MyBatisUtil.PAGE_SIZE_MAX < size ? MyBatisUtil.PAGE_SIZE_MAX : size;
        Wrapper<ProductMapping> wrapperWithAlias = MyBatisUtil.getIsActiveWrapper(orderBy, isAsc, ProductMappingMapper.ALIAS);
        MyBatisUtil.addAuthFilter(wrapperWithAlias, operator, ERPConstants.AUTH_TARGET_PRODUCT, false, true);
        List<ProductMapping> productMappings = productMappingService.findDetailListDynamic(current, size, wrapperWithAlias);

        Wrapper wrapper = MyBatisUtil.getIsActiveWrapper(orderBy, isAsc);
        MyBatisUtil.addAuthFilter(wrapper, operator, ERPConstants.AUTH_TARGET_PRODUCT, false, true);
        return new PageResultMessage<>(productMappings, productMappingService.selectCount(wrapper));
    }

    @ApiOperation(value = "更新产品对接")
    @ApiImplicitParam(name = "productMapping", value = "产品详细实体productMapping", required = true, dataType = "ProductMapping")
    @RequestMapping(method = RequestMethod.PUT)
    @ResponseStatus(HttpStatus.OK)
    public ResultMessage<ProductMapping> updateProductMappingById(@RequestBody ProductMapping productMapping, @ModelAttribute("user") User operator) {
        if (!ERPConstants.SYS_SUPER_USERNAME.equals(operator.getName())) {
            productMapping.setUpdateBy(operator.getId());
            productMapping.setCoco(operator.getCoco());
        }
        productMappingService.updateById(productMapping);
        return new ResultMessage<>(productMapping);
    }

    @ApiOperation(value = "同步平台产品")
    @RequestMapping(value = "/sync", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    @SuppressWarnings("unchecked")
    public PageResultMessage<List<ProductMapping>> syncProductMappings(@ModelAttribute("user") User operator) {
        List<CompCfg> compCfgs = compCfgService.loadCompCfgByCoco(operator.getCoco());
        List<ProductMapping> allProMappingList = new ArrayList<>();
        for (CompCfg compCfg : compCfgs) {
            ExtProductService wareSrv = extServiceFactory.getExtService(compCfg);
            if (wareSrv == null) {
                throw new RestServiceException(ResultCode.BAD_REQUEST);
            }
            // Load 3rd party products
            List<ProductMapping> newProductMappings = ExtServiceHelper.convertExtPro2ProMapping(wareSrv.searchAllProducts());
            // Load system product mappings
            Wrapper wrapper = MyBatisUtil.getIsActiveWrapper();
            MyBatisUtil.addAuthFilter(wrapper, operator, ERPConstants.AUTH_TARGET_PRODUCT, false, true);
            wrapper.eq(CommonFieldDef.EXT_PLATFORM, compCfg.getExtPlatform());
            List<ProductMapping> oldProductMappings = productMappingService.selectList(wrapper);
            for (ProductMapping mapping : newProductMappings) {
                MyBatisUtil.updateCommonFields(mapping, operator);
            }
            for (ProductMapping mapping : oldProductMappings) {
                MyBatisUtil.updateCommonFields(mapping, operator);
            }
            // Filter out saved product mappings
            newProductMappings = ExtServiceHelper.getNewProMappings(newProductMappings, oldProductMappings);
            if (CollectionUtils.isNotEmpty(newProductMappings)) {
                productMappingService.insertBatch(newProductMappings);
            }
            allProMappingList.addAll(newProductMappings);
        }
        return new PageResultMessage<>(allProMappingList, allProMappingList.size());
    }

    @ApiOperation(value = "导入平台产品")
    @RequestMapping(value = "/import/{ids}", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.OK)
    public ResultMessage importProductMappings(@PathVariable String ids, @ModelAttribute("user") User operator) {
        List<Long> idList = UtilityTool.convertStringArray2LongList(ids.split(","));
        try {
            List<ProductMapping> productMappings = productMappingService.selectBatchIds(idList);
            ExtProductService wareSrv = null;
            if (CollectionUtils.isNotEmpty(productMappings)) {
                wareSrv = extServiceFactory.getExtService(productMappings.get(0).getExtPlatform(), operator.getCoco());
            }
            if (wareSrv == null) {
                throw new RestServiceException(ResultCode.DELETE_NOT_FOUND);
            }
            List<ExtProduct> extProducts = wareSrv.searchAllProducts();
            for (ExtProduct entity : extProducts) {
                MyBatisUtil.updateCommonFields(entity, operator);
            }
            productMappingService.genProductSpecByProMappings(extProducts, productMappings);
            return new ResultMessage();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RestServiceException(ResultCode.DELETE_NOT_FOUND);
        }
    }

    @ApiOperation(value = "批量删除", notes = "根据url的id来指定删除对象")
    @ApiImplicitParam(name = "ids", value = "产品对接Id", required = true, dataType = "String")
    @RequestMapping(value = "/{ids}", method = RequestMethod.DELETE)
    @ResponseStatus(HttpStatus.OK)
    public ResultMessage deleteProductMappingById(@PathVariable String ids) {
        List<Long> list = UtilityTool.convertStringArray2LongList(ids.split(","));
        try {
            //Soft delete productMappings
            UtilityTool.softDelete(ProductMapping.class, list, productMappingService);
            return new ResultMessage();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RestServiceException(ResultCode.DELETE_NOT_FOUND);
        }
    }

}
